﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using FilterData;
using Common;

namespace ManagerMachine
{
    public class Table
    {
        int table_id;
        Socket client;
        IPAddress ip;
        int port;

        byte[] buffer = new byte[1024];
        byte[] dataSend;
        byte[] dataReceive;
        FilterDataManager filters;


        public Table(int id, Socket socket)
        {
            this.table_id = id;
            this.client = socket;
            IPEndPoint endpoint = (IPEndPoint)socket.RemoteEndPoint;
            ip = endpoint.Address;
            port = endpoint.Port;
            filters = new FilterDataManager();

        }

        #region Receive Data

        public void BeginReceive()
        {
            client.BeginReceive(buffer, 0, 2, SocketFlags.None, new AsyncCallback(OnSizeReceive), client);           
        }

        int SumSizeReceive = 0;
        int SizeReceived = 0;
        void OnSizeReceive(IAsyncResult ar)
        {
            try
            {
                if (!ar.IsCompleted)
                {
                    Console.WriteLine("Send Size Failed");
                    return;
                }
                client.EndReceive(ar);               
                SumSizeReceive = buffer[0];
                if (client.Connected)
                {
                    if (SumSizeReceive > 0)                    
                        client.BeginReceive(buffer, 2, SumSizeReceive, SocketFlags.None, new AsyncCallback(OnReceive), client); 
                    else
                        client.BeginReceive(buffer, 0, 2, SocketFlags.None, new AsyncCallback(OnSizeReceive), client);
                       
                }
            }
            catch (System.Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        void OnReceive(IAsyncResult ar)
        {
            try
            {
                if (!ar.IsCompleted)
                {
                    Console.WriteLine("Receive Error");
                    return;
                }
                SocketError error;
                int i = client.EndReceive(ar, out error);            
                if (i < 1)
                {
                    Console.WriteLine("Receive Error");
                    return;
                }
                SizeReceived += i;
                if (client.Connected)
                {
                    if (SizeReceived < SumSizeReceive)
                        client.BeginReceive(buffer, SizeReceived + 2, SumSizeReceive - SizeReceived, SocketFlags.None, new AsyncCallback(OnReceive), client);
                       
                    else
                    {
                        ProcessReceiveFullData();
                        ResetSumReceive();
                        client.BeginReceive(buffer, 0, 2, SocketFlags.None, new AsyncCallback(OnSizeReceive), client);
                      

                    }
                }



            }
            catch (System.Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        void ProcessReceiveFullData()
        {
            dataReceive = filters.ProcessDataReceive(buffer);
            if (ReceiveFromTable != null)
                ReceiveFromTable(client, new ReceiveFromTableEventArgs(dataReceive, this));
        }

        void ResetSumReceive()
        {
            SumSizeReceive = 0;
            SizeReceived = 0;
            buffer = new byte[1024];
        }
        #endregion

        #region SendData
        void SendData(byte[] data)
        {           
            dataSend = filters.ProcessDataSend(data);
            if (client.Connected)                
                client.BeginSend(dataSend, 0, dataSend.Length, SocketFlags.None, new AsyncCallback(OnSend), null);
        }
        public void SendMessage(MSG_GSM message,params object[] param)
        {
            List<byte> Data = new List<byte>();
            Data.Add((byte)message);
            foreach (object obj in param)
            {
                Data.Add((byte)(int)obj);
            }
            SendData(Data.ToArray());
        }
        public void SendMessage(MSG_GSM message, byte[] param)
        {
            List<byte> Data = new List<byte>();
            Data.Add((byte)message);
            Data.AddRange(param);
            SendData(Data.ToArray());
        }

        void OnSend(IAsyncResult ar)
        {
            try
            {
                if (!ar.IsCompleted || !client.Connected)
                    Console.WriteLine("Send no complete");
                client.EndSend(ar);            
            }
            catch (System.Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
        #endregion




        


        public int Table_ID
        {
            get { return table_id; }           
        }

        public event EventHandler<ReceiveFromTableEventArgs> ReceiveFromTable;
        
    }
}
